package com.rjj.wlqq.tool.io;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

public class FileKit {


    /**
     * 文件下载
     * <p>
     * 文件名编码后对于 空格变为+问题解决
     *
     * @param request  请求
     * @param response 响应
     * @param filePath 文件路径
     */
    public static void downloadResponse(String filePath, HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {

        //清空一下response对象，否则出现缓存什么的
        response.reset();
        response.addHeader("Cache-Control", "no-cache, no-store, must-revalidate");
        response.addHeader("charset", "utf-8");
        response.addHeader("Pragma", "no-cache");
        //指明这是一个下载的respond
        //response.setContentType("application/x-download,charset=utf-8");
        //response.setContentType("application/octet-stream");
        response.setContentType("application/force-download;charset=UTF-8");

        String fileName = getFileName(filePath);
        setContentDispositionHeader(response, fileName);

        File file = new File(filePath);
        byte[] buffer = new byte[1024];

        try (
                FileInputStream fis = new FileInputStream(file);
                BufferedInputStream bis = new BufferedInputStream(fis);
                OutputStream os = response.getOutputStream();
        ) {

            int i = bis.read(buffer);
            while (i != -1) {
                os.write(buffer);
                i = bis.read(buffer);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取文件名称加后缀
     *
     * @param filePath 文件地址 /a/a.xls
     * @return 文件名称加后缀 a.xls
     */
    public static String getFileName(String filePath) {
        if (filePath == null || "".equals(filePath)) {
            throw new RuntimeException("filePath is NULL or empty ");
        }
        return filePath.substring(filePath.lastIndexOf("/") + 1);
    }

    /**
     * 依据浏览器判断编码规则
     */
    public static String encodeFileName(HttpServletRequest request, String fileName) {
        String userAgent = request.getHeader("User-Agent");
        try {
            String encodedFileName = URLEncoder.encode(fileName, "UTF8");
            // 如果没有UA，则默认使用IE的方式进行编码
            if (userAgent == null) {
                return "filename=\"" + encodedFileName + "\"";
            }

            userAgent = userAgent.toLowerCase();
            // IE浏览器，只能采用URLEncoder编码
            if (userAgent.contains("msie")) {
                return "filename=\"" + encodedFileName + "\"";
            }

            // Opera浏览器只能采用filename*
            if (userAgent.contains("opera")) {
                return "filename*=UTF-8''" + encodedFileName;
            }

            // Safari浏览器，只能采用ISO编码的中文输出,Chrome浏览器，只能采用MimeUtility编码或ISO编码的中文输出
            if (userAgent.contains("safari") || userAgent.contains("applewebkit") || userAgent.contains("chrome")) {
                return "filename=\"" + new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1) + "\"";
            }

            // FireFox浏览器，可以使用MimeUtility或filename*或ISO编码的中文输出
            if (userAgent.contains("mozilla")) {
                return "filename*=UTF-8''" + encodedFileName;
            }

            return "filename=\"" + encodedFileName + "\"";
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 设置响应头
     * 现在时候的文件名称
     * response.setContentType("application/octet-stream")
     *
     * @param response 响应
     * @param fileName 文件名称 aa.xls
     */
    public static void setContentDispositionHeader(HttpServletResponse response, String fileName) throws UnsupportedEncodingException {
        String percentEncodedFileName = percentEncode(fileName);
        StringBuilder contentDispositionValue = new StringBuilder();
        contentDispositionValue.append("attachment; filename=")
                .append(percentEncodedFileName)
                .append(";")
                .append("filename*=")
                .append("utf-8''")
                .append(percentEncodedFileName);
        response.setHeader("Content-disposition", contentDispositionValue.toString());
    }

    /**
     * %20 空格编码问题
     * 对真实文件名中编码 空格变为加号问题解决
     *
     * @param fileName 文件名称 aa.xls
     * @return 编码后的文件名称
     */
    public static String percentEncode(String fileName) throws UnsupportedEncodingException {
        return URLEncoder
                .encode(fileName, StandardCharsets.UTF_8.toString())
                .replaceAll("\\+", "%20");

    }
}
